/** 
 * Copyright 2010 Erlacher Felix, Estgfaeller Wolfgang, Ferula Patrick
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package at.socialconference.web.client.ui;

import at.socialconference.inter.connection.protocol.SocketProtocol;
import at.socialconference.inter.model.User;
import at.socialconference.web.client.SCwebService;
import at.socialconference.web.client.controller.ViewController;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;

/**
 * This popup shows detailed information about a given user and allows the
 * visitor to add the user as a friend by clicking on a button.
 * 
 */
public class UserPopup extends PopupPanel implements ClickHandler {

	private User user;
	private FlexTable flexTable;
	private Button btnFriendRequest;
	private Button btnAcceptRequest;
	private Button btnRejectRequest;
	private LabelLinkedUser lblUserRequest;

	public UserPopup(User user) {
		this(user, false);
	}

	public UserPopup(User user, LabelLinkedUser lblUserRequest) {
		this(user, true);
		this.lblUserRequest = lblUserRequest;
	}

	/**
	 * Sets up the UserPopup
	 * 
	 * @param user
	 *            the User who has to be displayed
	 * @param friendRequest
	 *            if true accept and reject friendship buttons will be provided
	 * @wbp.parser.constructor
	 */
	public UserPopup(User user, boolean friendRequest) {
		super(true);
		this.user = user;
		setGlassEnabled(true);
		setTitle("Information about " + user.getFirstname() + " " + user.getLastname());

		flexTable = new FlexTable();

		int i = -1;

		flexTable.setWidget(++i, 0, new Label("Title"));
		flexTable.setWidget(i, 1, new Label(user.getTitle()));

		flexTable.setWidget(++i, 0, new Label("First Name"));
		flexTable.setWidget(i, 1, new Label(user.getFirstname()));

		flexTable.setWidget(++i, 0, new Label("Last Name"));
		flexTable.setWidget(i, 1, new Label(user.getLastname()));

		flexTable.setWidget(++i, 0, new Label("Country"));
		flexTable.setWidget(i, 1, new Label(user.getCountry()));

		flexTable.setWidget(++i, 0, new Label("Gender"));
		flexTable.setWidget(i, 1, new Label(user.getGender()));

		flexTable.setWidget(++i, 0, new Label("DBLP"));
		flexTable.setWidget(i, 1, new HTML("<a href=\"" + user.getDblp() + "\">"));

		flexTable.setWidget(++i, 0, new Label("Webpage"));
		flexTable.setWidget(i, 1, new HTML("<href>" + user.getWebpage() + "</href>"));
		
		// if this user is a friend show a more detailed version
		if (user.getSecurityLevel().equals(User.LEVEL_MEDIUM)) {

			flexTable.setWidget(++i, 0, new Label("Mail"));
			flexTable.setWidget(i, 1, new Label(user.getMail()));

			flexTable.setWidget(++i, 0, new Label("Phone"));
			flexTable.setWidget(i, 1, new Label(user.getPhone()));

			flexTable.setWidget(++i, 0, new Label("Address"));
			flexTable.setWidget(i, 1, new Label(user.getAddress()));

			flexTable.setWidget(++i, 0, new Label("City"));
			flexTable.setWidget(i, 1, new Label(user.getCity()));

			flexTable.setWidget(++i, 0, new Label("ZIP"));
			flexTable.setWidget(i, 1, new Label(user.getZip()));

		} else {
			User self = ViewController.getInstance().getClientUser();
			if (friendRequest == true) {
				// provide accept and reject friendship buttons
				btnAcceptRequest = new Button("Accept request");
				btnRejectRequest = new Button("Reject request");
				btnAcceptRequest.addClickHandler(this);
				btnRejectRequest.addClickHandler(this);
				HorizontalPanel hp = new HorizontalPanel();
				hp.getElement().getStyle().setPaddingTop(5, Unit.PX);
				btnAcceptRequest.getElement().getStyle().setPadding(2, Unit.PX);
				btnRejectRequest.getElement().getStyle().setPadding(2, Unit.PX);
				hp.add(btnAcceptRequest);
				hp.add(btnRejectRequest);
				hp.setCellHorizontalAlignment(btnAcceptRequest, HasHorizontalAlignment.ALIGN_CENTER);
				hp.setCellHorizontalAlignment(btnRejectRequest, HasHorizontalAlignment.ALIGN_CENTER);
				flexTable.setWidget(++i, 0, hp);
				flexTable.getFlexCellFormatter().setRowSpan(i, 0, 1);
			} else if (!self.getContacts().contains(user)){
				// provide a button that allows to send a friend request
				btnFriendRequest = new Button("Add as friend");
				btnFriendRequest.addClickHandler(this);
				HorizontalPanel hp = new HorizontalPanel();
				hp.getElement().getStyle().setPaddingTop(5, Unit.PX);
				hp.add(btnFriendRequest);
				hp.setCellHorizontalAlignment(btnFriendRequest, HasHorizontalAlignment.ALIGN_CENTER);
				flexTable.setWidget(++i, 0, hp);
				flexTable.getFlexCellFormatter().setRowSpan(i, 0, 1);
			}
		}
		
		flexTable.setWidget(++i, 0, new Label("QR-Code"));
		String code = "001bb00"+user.getId();
		
		Image img = new Image("QRCodeServlet?message="+code);
		img.setPixelSize(125, 125);
		flexTable.setWidget(i, 1, img);
		
		this.setWidget(flexTable);
		this.center();
	}

	// AsyncCallback implementation of the friendRequest method of the
	// web-service
	private class AsyncCallbackFriendRequest implements AsyncCallback<Integer> {
		@Override
		public void onSuccess(Integer result) {
			switch (result) {
			case SocketProtocol.OK:
				Window.alert("Friendship request sent successfully");
				break;
			case SocketProtocol.RESP_FSTATUS_FRIEND:
				Window.alert("This person is already a friend of you");
				break;
			case SocketProtocol.RESP_FSTATUS_PENDING:
				Window.alert("The person has already received a friendship request of you, but hasn't accepted it yet");
				break;
			case SocketProtocol.RESP_FSTATUS_YOURSELF:
				Window.alert("Really?! You were trying to add yourself as a friend?");
				break;
			case -1:
				Window.alert("Internal server error");
				break;
			default:
				Window.alert("Internal server error: illegal state");
				break;
			}
			hide();
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Server unreachable");
		}
	}
	
	private class AsyncCallbackRequestResponse implements AsyncCallback<Integer> {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Server unreachable");
		}

		@Override
		public void onSuccess(Integer result) {
			switch (result.intValue()) {
			case SocketProtocol.OK:
				lblUserRequest.removeFromParent();
				break;
			case SocketProtocol.RESP_FSTATUS_FRIEND:
			case SocketProtocol.RESP_FSTATUS_NOFRIENDSHIP:
				//DO NOTHING
				break;
			case -1:
				Window.alert("Internal server error: illegal state");
				break;
			default:
				Window.alert("Internal server error");
			}
			hide();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
	 * .dom.client.ClickEvent)
	 */
	public void onClick(ClickEvent event) {
		if (event.getSource().equals(btnFriendRequest)) {
			SCwebService.Util.getInstance().friendRequest(user.getId(), new AsyncCallbackFriendRequest());
			this.hide();
			this.clear();
		} else if (event.getSource().equals(btnAcceptRequest)) {
			SCwebService.Util.getInstance().acceptFriendRequest(user.getId(), new AsyncCallbackRequestResponse());
		} else if (event.getSource().equals(btnRejectRequest)) {
			SCwebService.Util.getInstance().rejectFriendRequest(user.getId(), new AsyncCallbackRequestResponse());
		}
	}

}
